package upe.mestrado.operadores.selecao;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import upe.mestrado.base.Individuo;
import upe.mestrado.base.OperadorSelecao;

public class Roleta implements OperadorSelecao {

	@Override
	public List<Individuo> executar(List<Individuo> populacao, int tamanhoMaximo) {

		//Soma os fitness
		double qtdTotalFitness = 0;
		for(Individuo individuo : populacao){
			qtdTotalFitness = qtdTotalFitness + individuo.getFitness();
		}

		//Seta probabilidade de cada individuo e torna false caso individuo ja tenha sido selecionado em outras ocasioes
		for(Individuo individuo : populacao){
			double perc = individuo.getFitness()/ qtdTotalFitness;
			
			individuo.setRouletteFitness(new RouletteFitness());
			individuo.getRouletteFitness().setPercOfFitness(perc);
			individuo.getRouletteFitness().setSelecionado(false);
		}
		
		//Ordena por melhores percentuais de fitness
		Collections.sort(populacao);
		
		//Atribui ao melhor fitness o maior percentual e ao pior fitness o pior percentual
		int pos =0;
		for (int i = populacao.size()-1; i >= 0; i--) {
			double percCrescente = populacao.get(pos).getRouletteFitness().getPercOfFitness();
		    double percDescrescente = populacao.get(i).getRouletteFitness().getPercOfFitness();
		    
		    populacao.get(pos).getRouletteFitness().setPercOfFitness(percDescrescente);
		    populacao.get(i).getRouletteFitness().setPercOfFitness(percCrescente);
		    pos++;
		}

		//Sorteia numero de tamanho max e adiciona a qtd certa de individuo
		Random random = new Random();
		List<Individuo> novaPopulacao = new ArrayList<Individuo>();

		for (int i = 0; i < tamanhoMaximo; i++) {
			double somaDosPercDosIndividuos = 0;
			boolean adicionouIndividuoLista = false;
			int randomPerc = random.nextInt(100);

			while(!adicionouIndividuoLista){
				for(int j=0; j<populacao.size(); j++){
					Individuo individuo = populacao.get(j);
					somaDosPercDosIndividuos = somaDosPercDosIndividuos + individuo.getRouletteFitness().getPercOfFitness()*100;

					if(somaDosPercDosIndividuos >= randomPerc){
						if(individuo.getRouletteFitness().isSelecionado()){
							j=0;
							randomPerc = random.nextInt(100);
							somaDosPercDosIndividuos = 0;
						}else{
							novaPopulacao.add(individuo);
							individuo.getRouletteFitness().setSelecionado(true);
							adicionouIndividuoLista = true;
							break;
						}
					}
				}
			}
		}
		return novaPopulacao;
	}

	@Override
	public Individuo executar(List<Individuo> populacao) {
		// TODO Auto-generated method stub
		return null;
	}

}
